import java.awt.Frame;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MenuBar;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.CheckboxMenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;//for CheckboxMenuItems
import java.awt.Toolkit;
import java.awt.MediaTracker;




public class MineSweeperWindow extends Frame implements WindowListener,//for closing
						ActionListener,// for menu items.
						ItemListener //for CheckBoxMenuItems

{

	/**
	*	The minesweeper game. The dimensions of this game dictate the 
	*	size of the window (as the window cannot be resized).
	**/
	private Game game;




	/**
	*	Menu items for the game and help menus.
	**/

	private CheckboxMenuItem menuGameTypes[];


	//what game difficulty is currently selected?
	private int currentGameDifficulty;


	private MenuItem newGame;
	private MenuItem quitGame;


	private CustomFieldDialog customField;

	public MineSweeperWindow()
	{
		super("Java Minesweeper");
		
		//lets load the images here.
				String image_prefix = "./images/";
				String image_suffix = ".gif";

				Image images[] = new Image[Game.NUMBER_OF_IMAGES];


				Toolkit tk = Toolkit.getDefaultToolkit();
				MineSweeperWindow msw = this;
				MediaTracker mt = new MediaTracker(msw);
				//load the first 8 images.
				for(int i=0;i< 9; i++){


					images[i] = tk.createImage(image_prefix + i + image_suffix);


				}
				//do the others
				images[Game.IMG_SMILEY_SMILE] = tk.createImage(image_prefix +
												"smiley_smile" + image_suffix);
				images[Game.IMG_SMILEY_O] = tk.createImage(image_prefix +
												"smiley_ooo" + image_suffix);
				images[Game.IMG_SMILEY_DEAD] = tk.createImage(image_prefix +
												"smiley_dead" + image_suffix);
				images[Game.IMG_SMILEY_GLASSES] = tk.createImage(image_prefix +
												"smiley_glasses" + image_suffix);
				images[Game.IMG_FLAG] = tk.createImage(image_prefix + "flag" + image_suffix);
				images[Game.IMG_QUESTION_MARK] = tk.createImage(image_prefix +
												"question_mark" + image_suffix);
				images[Game.IMG_MINE] = tk.createImage(image_prefix + "mine" + image_suffix);     
				images[Game.IMG_LED_TOP_ON] = tk.createImage(image_prefix + 
												"LED_top_1" + image_suffix);
				images[Game.IMG_LED_TOP_OFF] = tk.createImage(image_prefix + 
												"LED_top_0" + image_suffix);
				images[Game.IMG_LED_LEFT_ON] = tk.createImage(image_prefix + 
												"LED_left_1" + image_suffix);
				images[Game.IMG_LED_LEFT_OFF] = tk.createImage(image_prefix + 
												"LED_left_0" + image_suffix);
				images[Game.IMG_LED_RIGHT_ON] = tk.createImage(image_prefix + 
												"LED_right_1" + image_suffix);
				images[Game.IMG_LED_RIGHT_OFF] = tk.createImage(image_prefix + 
												"LED_right_0" + image_suffix);
				images[Game.IMG_LED_MID_ON] = tk.createImage(image_prefix + 
												"LED_mid_1" + image_suffix);
				images[Game.IMG_LED_MID_OFF] = tk.createImage(image_prefix + 
												"LED_mid_0" + image_suffix);
				images[Game.IMG_LED_BOTTOM_ON] = tk.createImage(image_prefix + 
												"LED_bottom_1" + image_suffix);
				images[Game.IMG_LED_BOTTOM_OFF] = tk.createImage(image_prefix + 
												"LED_bottom_0" + image_suffix);
				images[Game.IMG_CELL_TOUCHED] = tk.createImage(image_prefix + 
												"cell_touched" + image_suffix);
				images[Game.IMG_CELL_UNTOUCHED] = tk.createImage(image_prefix + 
												"cell_untouched" + image_suffix);
				images[Game.IMG_ICON] = tk.createImage(image_prefix + "icon" + image_suffix);
				images[Game.IMG_SMILEY_PRESSED] = tk.createImage(image_prefix +
												"smiley_pressed" + image_suffix);

				

				
				for(int i=0;i< Game.NUMBER_OF_IMAGES; i++)
				{

//					System.out.println("Loading image "+(i+1));
					mt.addImage(images[i],i);
					try
					{
						mt.waitForID(i);
					}catch (InterruptedException ioe)
					{
						System.out.println("Interrupted loading images..");
					}


				}


				msw.init(images);
		
	}




	public void init(Image[] images)
	{

		setupMenus();

		game = new Game(images);
		setGameDifficulty(Game.GAME_DIFFICULTY_BEGINNER);
		game.setVisible(true);


		addWindowListener(this);
		addMouseMotionListener(game);
		addMouseListener(game);
		add(game);
		pack();
		setSize(game.getTotalWidth() + getInsets().left + getInsets().right,
			game.getTotalHeight() + getInsets().top + getInsets().bottom);//plus the height of the menu...


		setIconImage(Game.images[Game.IMG_ICON]);
		setLocation(300,300);
		customField = new CustomFieldDialog(this,Game.EASY_WIDTH,
												Game.EASY_HEIGHT,
												Game.EASY_NUM_MINES);
		game.setSize(game.getTotalWidth() + getInsets().left + getInsets().right,
				game.getTotalHeight()+ getInsets().top + getInsets().bottom);

		setSize(game.getTotalWidth() + getInsets().left + getInsets().right,
				game.getTotalHeight()+ getInsets().top + getInsets().bottom);


		setVisible(true);
		setResizable(false);


	}

	private void setupMenus()
	{

		MenuBar menuBar = new MenuBar();
		Menu menu = new Menu("Game");

		newGame = new MenuItem("New");
		quitGame = new MenuItem("Quit");

		newGame.addActionListener(this);
		quitGame.addActionListener(this);

		menu.add(newGame);
		menu.add("-");

		menuGameTypes = new CheckboxMenuItem[4];

		menuGameTypes[Game.GAME_DIFFICULTY_BEGINNER] = 
				new CheckboxMenuItem("Beginner");
		menu.add(menuGameTypes[Game.GAME_DIFFICULTY_BEGINNER]);




		menuGameTypes[Game.GAME_DIFFICULTY_INTERMEDIATE] = 
				new CheckboxMenuItem("Intermediate");
		menu.add(menuGameTypes[Game.GAME_DIFFICULTY_INTERMEDIATE]);

		menuGameTypes[Game.GAME_DIFFICULTY_EXPERT] = 
				new CheckboxMenuItem("Expert");
		menu.add(menuGameTypes[Game.GAME_DIFFICULTY_EXPERT]);

		menuGameTypes[Game.GAME_DIFFICULTY_CUSTOM] = 
				new CheckboxMenuItem("Custom...");
		menu.add(menuGameTypes[Game.GAME_DIFFICULTY_CUSTOM]);

		menuGameTypes[Game.GAME_DIFFICULTY_BEGINNER].addItemListener(this);
		menuGameTypes[Game.GAME_DIFFICULTY_INTERMEDIATE].addItemListener(this);
		menuGameTypes[Game.GAME_DIFFICULTY_EXPERT].addItemListener(this);
		menuGameTypes[Game.GAME_DIFFICULTY_CUSTOM].addItemListener(this);

		menu.add(new CheckboxMenuItem("-"));
		menu.add(quitGame);

		setGameDifficulty(Game.GAME_DIFFICULTY_BEGINNER);

		menuBar.add(menu);
		setMenuBar(menuBar);


	}
	public Game getGame() {
		return this.game;
	}

	private void kill()
	{
		if(game != null)
		{
			game.stopGame();
		}
		dispose();
		game = null;
		/*try{
			finalize();
		}catch(Exception e){}
		Runtime.getRuntime().gc();
		  */
	}

	//---------------------------------
	//---------------------------------

	/**
	*	WindowListener interface implementation of windowOpened()
	**/

	public void windowOpened(WindowEvent e)
	{

	}

	/**
	*	WindowListener interface implementation of windowClosing()
	**/ 
	public void windowClosing(WindowEvent e)
	{

		//kill the app...
		kill();
		//this.windowIconified(e);

	}

	/**
	*	WindowListener interface implementation of windowClosed()
	**/
	public void windowClosed(WindowEvent e)
	{


	}

	/**
	*	WindowListener interface implementation of windowIconified()
	**/
	public void windowIconified(WindowEvent e)
	{

	}


	/**
	*	WindowListener interface implementation of windowDeiconified()
	**/
	public void windowDeiconified(WindowEvent e)
	{


	}

	/**
	*	WindowListener interface implementation of windowActivated()
	**/
	public void windowActivated(WindowEvent e)
	{


	}

	/**
	*	WindowListener interface implementation of windowDeactivated()
	**/
	public void windowDeactivated(WindowEvent e)
	{


	}


	//
	// ActionListener interface method implementation.
	//

	public void actionPerformed(ActionEvent e)  
 
	{


		if(e.getSource().equals(newGame))
		{
			game.newGame();
		}else if(e.getSource().equals(quitGame))
		{
			kill();
		}
//		System.out.println("eventDispatched:"+e.toString());

	}


	//
	// ItemListener interface method implementation.
	//
	public void itemStateChanged(ItemEvent e) 
	{

//		System.out.println("@"+e.toString());

		CheckboxMenuItem menuitem = (CheckboxMenuItem)(e.getItemSelectable());
		if(menuitem == menuGameTypes[Game.GAME_DIFFICULTY_BEGINNER])
		{
				setGameDifficulty(Game.GAME_DIFFICULTY_BEGINNER);
		}else if (menuitem == menuGameTypes[Game.GAME_DIFFICULTY_INTERMEDIATE])
		{
				setGameDifficulty(Game.GAME_DIFFICULTY_INTERMEDIATE);
		}else if (menuitem == menuGameTypes[Game.GAME_DIFFICULTY_EXPERT])
		{
				setGameDifficulty(Game.GAME_DIFFICULTY_EXPERT);
		}else
		{
				setGameDifficulty(Game.GAME_DIFFICULTY_CUSTOM);
				customField.setVisible(true);

		}

		game.setDifficulty(currentGameDifficulty,
							customField.getWidth(),
							customField.getHeight(),
							customField.getNumberOfMines());

		game.stopGame();
		System.out.println("Bottom insets:"+getInsets().bottom);
		setSize(game.getTotalWidth() + getInsets().left + getInsets().right,
				game.getTotalHeight()+ getInsets().top + getInsets().bottom);

	}

	public void setGameDifficulty(int newGameDifficulty)
	{

			if(newGameDifficulty < 0  || newGameDifficulty > menuGameTypes.length)
			{
				throw new IllegalArgumentException("Error: Game difficulty "+
					"setting must be between 0 and "+(menuGameTypes.length -1)+
					", not "+newGameDifficulty);

			}

			menuGameTypes[currentGameDifficulty].setState(false);
			currentGameDifficulty = newGameDifficulty;
			menuGameTypes[currentGameDifficulty].setState(true);
			
	}

}
